#include "CAN_driver.h"

// if can bus is too busy to send frame,  hcan->ErrorCode |= HAL_CAN_ERROR_PARAM will be performed , pay attention 
/**
 * \brief CAN邮箱发送，发送数据以字节为单位
 * \param[in] hcan CAN总线控制句柄
 * \param[in] std_id 目标节点标识符 
 * \param[in] aData 数据缓冲数组
 */ 
void CANTransmit_U8(CAN_HandleTypeDef *hcan, uint32_t std_id, uint8_t aData[])
{
    CAN_TxHeaderTypeDef TxHeader;                                                 
    TxHeader.StdId = std_id;                                                      
    TxHeader.IDE = CAN_ID_STD;                                                    
    TxHeader.RTR = CAN_RTR_DATA;                                                     
    TxHeader.DLC = 8;                                                             
		if(hcan == &hcan1)
			HAL_CAN_AddTxMessage(hcan, &TxHeader, aData, (uint32_t*)CAN_TX_MAILBOX0);   
		else if(hcan == &hcan2)
			HAL_CAN_AddTxMessage(hcan, &TxHeader, aData, (uint32_t*)CAN_TX_MAILBOX1);   
		else return;
}

/**
 * \brief CAN邮箱发送，发送数据以uint16_t为单位
 * \param[in] hcan CAN总线控制句柄
 * \param[in] std_id 目标节点标识符 
 * \param[in] uint16_t data1 data2 data3 data4
 */ 
void CANTransmit_I16(CAN_HandleTypeDef *hcan, uint32_t std_id, int16_t output1, int16_t output2, int16_t output3, int16_t output4)
{
    CAN_TxHeaderTypeDef TxHeader;                                                 
    TxHeader.StdId = std_id;                                                      
    TxHeader.IDE = CAN_ID_STD;                                                    
    TxHeader.RTR = CAN_RTR_DATA;                                                     
    TxHeader.DLC = 8;                
	uint8_t aData[8] = {0};
	aData[0] = (uint8_t)(output1 >> 8);		
	aData[1] = (uint8_t)output1;
	aData[2] = (uint8_t)(output2 >> 8);
	aData[3] = (uint8_t)output2;
	aData[4] = (uint8_t)(output3 >> 8);
	aData[5] = (uint8_t)output3;
	aData[6] = (uint8_t)(output4 >> 8);
	aData[7] = (uint8_t)output4;		
	if(hcan == &hcan1)
		HAL_CAN_AddTxMessage(hcan, &TxHeader, aData, (uint32_t*)CAN_TX_MAILBOX0);   
	else if(hcan == &hcan2)
		HAL_CAN_AddTxMessage(hcan, &TxHeader, aData, (uint32_t*)CAN_TX_MAILBOX1);   
	else return;
}


/**
 * \brief CAN初始化启动,配置滤波器
 * \param[in] hcan CAN总线控制句柄
 */

void CANInitialize(CAN_HandleTypeDef *hcan)
{
    uint32_t FilterBank, FilterFIFO;                              /*滤波器邮箱变量*/
    CAN_FilterTypeDef sFilterConfig;                              /*CAN滤波器结构体*/
    if(hcan == &hcan1)                                            /*CAN1滤波器、邮箱设置*/
    {
        FilterBank = 0;                                           /*滤波器从0开始*/
        FilterFIFO = CAN_RX_FIFO0;                                /*CAN1关联邮箱FIFO0*/
    } 
    else if(hcan == &hcan2)                                       /*CAN2滤波器设置*/
    {           
        FilterBank = 14;                                          /*滤波器从14开始*/
        FilterFIFO = CAN_RX_FIFO1;                                /*CAN2关联邮箱FIFO1*/  
    }
    else
    {
        return;
    }
    sFilterConfig.FilterBank = FilterBank;                        /*配置滤波器结构体过滤器组*/
    sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;             /*配置滤波器模式为标识符屏蔽模式*/
    sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;            /*配置滤波器长度32位*/
    sFilterConfig.FilterIdHigh = 0x0000;                          /*配置滤波器标识符高八位*/
    sFilterConfig.FilterIdLow = 0x0000;                           /*配置滤波器标识符低八位*/
    sFilterConfig.FilterMaskIdHigh = 0x0000;                      /*配置屏蔽符高八位*/
    sFilterConfig.FilterMaskIdLow = 0x0000;                       /*配置屏蔽符低八位*/
    sFilterConfig.FilterFIFOAssignment = FilterFIFO;              /*配置滤波器关联邮箱FIFO0*/
    sFilterConfig.FilterActivation = ENABLE;                      /*设置滤波器使能位*/
    sFilterConfig.SlaveStartFilterBank = 14;                      /*不知*/
    HAL_CAN_ConfigFilter(hcan, &sFilterConfig);                   /*应用滤波器配置*/
    HAL_CAN_Start(hcan);                                          /*开启CAN*/
}

/**
 * \brief 使能CAN接收等待中断
 * \param[in] hcan CAN总线控制句柄 
 */
void CANReceiveEnable(CAN_HandleTypeDef *hcan)              
{
    uint32_t ActiveITs;
    if(hcan == &hcan1)
        ActiveITs = CAN_IT_RX_FIFO0_MSG_PENDING;
    else if(hcan == &hcan2)
        ActiveITs = CAN_IT_RX_FIFO1_MSG_PENDING;
    else
        return;    
    HAL_CAN_ActivateNotification(hcan, ActiveITs);                  /*使能CAN邮箱消息等待中断*/  
}
